﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Npgsql;
using NpgsqlTypes;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.ComponentModel;

namespace DdReader
{
    class MeasureData
    {
        public const int HowDeepToScan = 4;
        bool endian;
        // исходный массив
        byte[] b = new byte[223060];
        // переменные для заголовка
        DateTime mDateTime;
        ushort seans, nr1, nr0;
        // мощность сигнала
        uint[] m680 = new uint[680];
        uint[,] akf = new uint[170, 18];
        uint[] adc = new uint[680];
        ushort[] serv = new ushort[180];
        // v format
        uint[,] dat1 = new uint[230, 10];
        uint[,] dat2 = new uint[230, 10];
        uint[] apower = new uint[230];
        uint[] nadc1 = new uint[230];
        uint[] nadc2 = new uint[230];
        uint[] vserv = new uint[230];

        // s new format
        uint[,] akf1 = new uint[680, 19];
        uint[,] akf2 = new uint[680, 19];
        uint[,] akf3 = new uint[680, 19];
        uint[,] akf4 = new uint[680, 19];
        uint[] ipower1 = new uint[680];
        uint[] ipower2 = new uint[680];
        uint[] nsadc1 = new uint[680];
        uint[] nsadc2 = new uint[680];
        uint[] nsadc3 = new uint[680];
        uint[] nsadc4 = new uint[680];
        
        NpgsqlConnection conn;

        public NpgsqlConnection Conn
        {
            get { return conn; }
            set { conn = value; }
        }

        NpgsqlCommand commandv, commands,commandS;
        string command_s, command_v, command_S;
        string dirname;

        public string Dirname
        {
            get { return dirname; }
            set { dirname = value; }
        }

        Int32 rowsaffected;
        Int32 iicount;

        public Int32 Iicount
        {
            get { return iicount; }
            set { iicount = value; }
        }

        public void Init()
        {
            iicount = 0;
            endian = BitConverter.IsLittleEndian;
            command_s = @"INSERT INTO format_s(
            measure_date,nr0,nr1,seans, power, acf, adc_null, 
            slabel)
            VALUES (:p_date, :p_nr0,:p_nr1,:p_seans ,:p_power, :p_akf, :p_adc, :p_slabel)";
            command_v = @"INSERT INTO format_v(measure_date, seans, nr0, nr1, dat1, dat2, apower, adc1_null, 
                                                adc2_null, alabel)
                                        VALUES (:p_date, :p_seans, :p_nr0, :p_nr1, :p_dat1, :p_dat2, :p_apower, :p_adc1_null,
                                                :p_adc2_null, :p_alabel)";
            command_S = @"INSERT INTO format_snew(
                            measure_date, seans, nr0, nr1, akf1, akf2, akf3, akf4, adc_null1, 
                            adc_null2, adc_null3, adc_null4, power1, power2)
                        VALUES (:p_date, :p_seans, p_nr0, :p_nr1, :p_akf1, :p_akf2, :p_akf3, :p_akf4, 
                                :p_adc1_null, :p_adc2_null, :p_adc3_null, :p_adc4_null, :p_power1, :p_power2)";
            conn = new NpgsqlConnection("Server=217.12.215.17;Port=5432;User Id=ax;Password=658706;Database=ions;");

            conn.Open();

            commands = new NpgsqlCommand(command_s, conn);
            commands.Parameters.Add(new NpgsqlParameter("p_date", NpgsqlDbType.Timestamp));
            commands.Parameters.Add(new NpgsqlParameter("p_nr0", NpgsqlDbType.Integer));
            commands.Parameters.Add(new NpgsqlParameter("p_nr1", NpgsqlDbType.Integer));
            commands.Parameters.Add(new NpgsqlParameter("p_seans", NpgsqlDbType.Integer));
            commands.Parameters.Add(new NpgsqlParameter("p_power", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commands.Parameters.Add(new NpgsqlParameter("p_akf", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commands.Parameters.Add(new NpgsqlParameter("p_adc", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commands.Parameters.Add(new NpgsqlParameter("p_slabel", NpgsqlDbType.Array | NpgsqlDbType.Integer));
            //commands.Prepare();
            commandv = new NpgsqlCommand(command_v, conn);
            commandv.Parameters.Add(new NpgsqlParameter("p_date", NpgsqlDbType.Timestamp));
            commandv.Parameters.Add(new NpgsqlParameter("p_nr0", NpgsqlDbType.Integer));
            commandv.Parameters.Add(new NpgsqlParameter("p_nr1", NpgsqlDbType.Integer));
            commandv.Parameters.Add(new NpgsqlParameter("p_seans", NpgsqlDbType.Integer));
            commandv.Parameters.Add(new NpgsqlParameter("p_dat1", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandv.Parameters.Add(new NpgsqlParameter("p_dat2", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandv.Parameters.Add(new NpgsqlParameter("p_apower", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandv.Parameters.Add(new NpgsqlParameter("p_adc1_null", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandv.Parameters.Add(new NpgsqlParameter("p_adc2_null", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandv.Parameters.Add(new NpgsqlParameter("p_alabel", NpgsqlDbType.Array | NpgsqlDbType.Integer));
            //commandv.Prepare();

            commandS = new NpgsqlCommand(command_S, conn);
            commandS.Parameters.Add(new NpgsqlParameter("p_date", NpgsqlDbType.Timestamp));
            commandS.Parameters.Add(new NpgsqlParameter("p_nr0", NpgsqlDbType.Integer));
            commandS.Parameters.Add(new NpgsqlParameter("p_nr1", NpgsqlDbType.Integer));
            commandS.Parameters.Add(new NpgsqlParameter("p_seans", NpgsqlDbType.Integer));
            commandS.Parameters.Add(new NpgsqlParameter("p_akf1", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandS.Parameters.Add(new NpgsqlParameter("p_akf2", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandS.Parameters.Add(new NpgsqlParameter("p_akf3", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandS.Parameters.Add(new NpgsqlParameter("p_akf4", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandS.Parameters.Add(new NpgsqlParameter("p_power1", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandS.Parameters.Add(new NpgsqlParameter("p_power2", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandS.Parameters.Add(new NpgsqlParameter("p_adc1_null", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandS.Parameters.Add(new NpgsqlParameter("p_adc2_null", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandS.Parameters.Add(new NpgsqlParameter("p_adc3_null", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            commandS.Parameters.Add(new NpgsqlParameter("p_adc4_null", NpgsqlDbType.Array | NpgsqlDbType.Bigint));
            //commandv.Prepare();
        }

        public void ProccesFile(string sfile, BackgroundWorker backgroundWorker)
        {
            int ibw = 0;
            int start = 0;
            try
            {
                Array.Clear(b, 0, b.Length);
                Array.Clear(m680, 0, m680.Length);
                Array.Clear(akf, 0, akf.Length);
                Array.Clear(adc, 0, adc.Length);
                Array.Clear(serv, 0, serv.Length);
                // v format
                Array.Clear(dat1, 0, dat1.Length);
                Array.Clear(dat2, 0, dat2.Length);
                Array.Clear(apower, 0, apower.Length);
                Array.Clear(nadc1, 0, nadc1.Length);
                Array.Clear(nadc2, 0, nadc2.Length);
                Array.Clear(vserv, 0, vserv.Length);
                //s new format
                Array.Clear(akf1, 0, akf1.Length);
                Array.Clear(akf2, 0, akf2.Length);
                Array.Clear(akf3, 0, akf3.Length);
                Array.Clear(akf4, 0, akf4.Length);
                Array.Clear(ipower1, 0, ipower1.Length);
                Array.Clear(ipower2, 0, ipower2.Length);
                Array.Clear(nsadc1, 0, nsadc1.Length);
                Array.Clear(nsadc2, 0, nsadc2.Length);
                Array.Clear(nsadc3, 0, nsadc3.Length);
                Array.Clear(nsadc4, 0, nsadc4.Length);

                FileInfo f = new FileInfo(sfile);
                long s1 = f.Length;
                switch (s1)
                {
                    case 18360:
                    case 21200:
                    case 22460:
                    case 223060:
                        using (FileStream fs = File.OpenRead(sfile))
                        {
                            fs.Read(b, 0, (int)s1);
                        }
                        if (endian) Array.Reverse(b, 0, 18);
                        nr1 = BitConverter.ToUInt16(b, 0);
                        nr0 = BitConverter.ToUInt16(b, 2);
                        seans = BitConverter.ToUInt16(b, 4);
                        // lbNr1.Text = nr1.ToString();
                        //lbNr0.Text = nr0.ToString();
                        //lbSeans.Text = seans.ToString();
                        string ts = BitConverter.ToUInt16(b, 16).ToString() + '/' + BitConverter.ToUInt16(b, 14).ToString() +
                        '/' + BitConverter.ToUInt16(b, 12).ToString() + ' ' + BitConverter.ToUInt16(b, 10).ToString() + ':' + BitConverter.ToUInt16(b, 8).ToString() +
                        ':' + BitConverter.ToUInt16(b, 6).ToString();

                        bool rezult = DateTime.TryParse(ts, out mDateTime);
                        if (rezult)
                        {
                            //  lbDate.Text = mDateTime.ToString("D");
                        }
                        else
                        {
                            Log.WriteErrorLog(String.Format("Неверная дата {0}", sfile));
                            return;
                        }

                        break;
                    default:
                        Log.WriteErrorLog(String.Format("Неверный тип файла {0}", sfile));
                        return;
                    //break;
                }
                //Open the stream and read it back.

                switch (s1)
                {
                    case 18360:
                        //S старый
                        // преобразование из массива byte  в массив uint (dword)

                        start = 20;
                        for (int i = 0; i < 680; i++)
                        {

                            if (endian) Array.Reverse(b, start, 4);
                            m680[i] = BitConverter.ToUInt32(b, start);
                            start += 4;
                        }

                        // АКФ
                        //2740
                        for (int i = 0; i < 170; i++)
                        {
                            for (int j = 0; j < 18; j++)
                            {
                                //20+680*4  ..680 * 4 + 18 * 4 * i + j * 4
                                if (endian) Array.Reverse(b, start, 4);
                                akf[i, j] = BitConverter.ToUInt32(b, start);
                                start += 4;
                            }
                        }

                        //  14980
                        // ноль AЦП
                        for (int i = 0; i < 680; i++)
                        {

                            if (endian) Array.Reverse(b, start, 4);
                            m680[i] = BitConverter.ToUInt32(b, start);
                            start += 4;
                        }

                        start += 300;//300 байт свободное пространство 18000
                        // служебная информация
                        for (int i = 0; i < 180; i++)
                        {

                            if (endian) Array.Reverse(b, start, 2);
                            serv[i] = BitConverter.ToUInt16(b, start);
                            start += 2;
                        }
                        // для проверки на типе s = 18 360

                        commands.Parameters["p_date"].Value = mDateTime;
                        commands.Parameters["p_nr0"].Value = nr0;
                        commands.Parameters["p_nr1"].Value = nr1;
                        commands.Parameters["p_seans"].Value = seans;
                        commands.Parameters["p_power"].Value = m680;
                        commands.Parameters["p_akf"].Value = akf;
                        commands.Parameters["p_adc"].Value = adc;
                        commands.Parameters["p_slabel"].Value = serv;
                        try
                        {

                            rowsaffected = commands.ExecuteNonQuery();
                            iicount += 1;
                            ibw += 1;
                            if ( ibw >= 100) ibw =0;
                            backgroundWorker.ReportProgress(ibw);

                            //MessageBox.Show(String.Format("It was added {0} lines in table table1", rowsaffected));
                        }
                        catch (Exception ex)
                        {
                            Log.WriteErrorLog(ex.Message);
                        }

                        break;
                    case 21200:
                    case 22460:
                        //V вариант 1
                        start = 20;
                        for (int i = 0; i < 230; i++)
                        {
                            //считываем dat1 и dat2 и мощность
                            //20+680*4  ..680 * 4 + 18 * 4 * i + j * 4
                            if (endian) Array.Reverse(b, start, 4);
                            dat1[i, 0] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat2[i, 0] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            apower[i] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat1[i, 1] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat2[i, 1] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat1[i, 2] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat2[i, 2] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat1[i, 3] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat2[i, 3] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat1[i, 4] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat2[i, 4] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat1[i, 5] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat2[i, 5] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat1[i, 6] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat2[i, 6] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat1[i, 7] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat2[i, 7] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat1[i, 8] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat2[i, 8] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat1[i, 9] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            dat2[i, 9] = BitConverter.ToUInt32(b, start);
                            start += 4;

                        }
                        for (int i = 0; i < 230; i++)
                        { // считываем нуль АЦП1 и АЦП2
                            if (endian) Array.Reverse(b, start, 4);
                            nadc1[i] = BitConverter.ToUInt32(b, start);
                            start += 4;
                            if (endian) Array.Reverse(b, start, 4);
                            nadc2[i] = BitConverter.ToUInt32(b, start);
                            start += 4;
                        }
                        if (s1 == 22420)
                        {
                            // 820 байт не используются
                            start += 820;
                            for (int i = 0; i < 230; i++)
                            {
                                //считываем метки 230 word
                                if (endian) Array.Reverse(b, start, 2);
                                vserv[i] = BitConverter.ToUInt32(b, start);
                                start += 2;
                            }
                        }
                        commandv.Parameters["p_date"].Value = mDateTime;
                        commandv.Parameters["p_nr0"].Value = nr0;
                        commandv.Parameters["p_nr1"].Value = nr1;
                        commandv.Parameters["p_seans"].Value = seans;
                        commandv.Parameters["p_dat1"].Value = dat1;
                        commandv.Parameters["p_dat2"].Value = dat2;
                        commandv.Parameters["p_apower"].Value = apower;
                        commandv.Parameters["p_adc1_null"].Value = nadc1;
                        commandv.Parameters["p_adc2_null"].Value = nadc2;
                        commandv.Parameters["p_alabel"].Value = vserv;

                        try
                        {

                            rowsaffected = commandv.ExecuteNonQuery();
                            iicount += 1;
                            ibw += 1;
                            if (ibw >= 100) ibw = 0;
                            backgroundWorker.ReportProgress(ibw);

                            //MessageBox.Show(String.Format("It was added {0} lines in table table1", rowsaffected));
                        }
                        catch (Exception ex)
                        {
                            Log.WriteErrorLog(ex.Message);
                        }
                        break;
                    case 223060:
                        //S новый
                        start = 20;

                        // АКФ1
                        //
                        for (int i = 0; i < 680; i++)
                        {
                            for (int j = 0; j < 19; j++)
                            {
                                //20+680*4  ..680 * 4 + 18 * 4 * i + j * 4
                                if (endian) Array.Reverse(b, start, 4);
                                akf1[i, j] = BitConverter.ToUInt32(b, start);
                                start += 4;
                            }
                        }
                        // АКФ2
                        //
                        for (int i = 0; i < 680; i++)
                        {
                            for (int j = 0; j < 19; j++)
                            {
                                //20+680*4  ..680 * 4 + 18 * 4 * i + j * 4
                                if (endian) Array.Reverse(b, start, 4);
                                akf2[i, j] = BitConverter.ToUInt32(b, start);
                                start += 4;
                            }
                        }
                        // АКФ3
                        //
                        for (int i = 0; i < 680; i++)
                        {
                            for (int j = 0; j < 19; j++)
                            {
                                //20+680*4  ..680 * 4 + 18 * 4 * i + j * 4
                                if (endian) Array.Reverse(b, start, 4);
                                akf3[i, j] = BitConverter.ToUInt32(b, start);
                                start += 4;
                            }
                        }
                        // АКФ4
                        //
                        for (int i = 0; i < 680; i++)
                        {
                            for (int j = 0; j < 19; j++)
                            {
                                //20+680*4  ..680 * 4 + 18 * 4 * i + j * 4
                                if (endian) Array.Reverse(b, start, 4);
                                akf4[i, j] = BitConverter.ToUInt32(b, start);
                                start += 4;
                            }
                        }

                        //  
                        // ноль AЦП 1
                        for (int i = 0; i < 680; i++)
                        {

                            if (endian) Array.Reverse(b, start, 4);
                            nsadc1[i] = BitConverter.ToUInt32(b, start);
                            start += 4;
                        }
                        //  
                        // ноль AЦП 2
                        for (int i = 0; i < 680; i++)
                        {

                            if (endian) Array.Reverse(b, start, 4);
                            nsadc2[i] = BitConverter.ToUInt32(b, start);
                            start += 4;
                        }
                        //  
                        // ноль AЦП 3
                        for (int i = 0; i < 680; i++)
                        {

                            if (endian) Array.Reverse(b, start, 4);
                            nsadc3[i] = BitConverter.ToUInt32(b, start);
                            start += 4;
                        }
                        //  
                        // ноль AЦП 4
                        for (int i = 0; i < 680; i++)
                        {

                            if (endian) Array.Reverse(b, start, 4);
                            nsadc4[i] = BitConverter.ToUInt32(b, start);
                            start += 4;
                        }
                        // мощьность по короткому импульсу 1
                        for (int i = 0; i < 680; i++)
                        {

                            if (endian) Array.Reverse(b, start, 4);
                            ipower1[i] = BitConverter.ToUInt32(b, start);
                            start += 4;
                        }
                        // мощьность по короткому импульсу 2
                        for (int i = 0; i < 680; i++)
                        {

                            if (endian) Array.Reverse(b, start, 4);
                            ipower2[i] = BitConverter.ToUInt32(b, start);
                            start += 4;
                        }


                        commands.Parameters["p_date"].Value = mDateTime;
                        commands.Parameters["p_nr0"].Value = nr0;
                        commands.Parameters["p_nr1"].Value = nr1;
                        commands.Parameters["p_seans"].Value = seans;
                        commands.Parameters["p_power1"].Value = ipower1;
                        commands.Parameters["p_power2"].Value = ipower2;
                        commands.Parameters["p_akf1"].Value = akf1;
                        commands.Parameters["p_akf2"].Value = akf2;
                        commands.Parameters["p_akf3"].Value = akf3;
                        commands.Parameters["p_akf4"].Value = akf4;
                        commands.Parameters["p_adc1_null"].Value = nsadc1;
                        commands.Parameters["p_adc2_null"].Value = nsadc2;
                        commands.Parameters["p_adc3_null"].Value = nsadc3;
                        commands.Parameters["p_adc4_null"].Value = nsadc4;
                        try
                        {

                            rowsaffected = commandS.ExecuteNonQuery();
                            iicount += 1;
                            ibw += 1;
                            if (ibw >= 100) ibw = 0;
                            backgroundWorker.ReportProgress(ibw);

                            //MessageBox.Show(String.Format("It was added {0} lines in table table1", rowsaffected));
                        }
                        catch (Exception ex)
                        {
                            Log.WriteErrorLog(ex.Message);
                        }

                        break;
                    default:
                        Log.WriteErrorLog(String.Format("Неверный тип файла {0}", sfile));
                        return;
                    // break;
                }

            }
            catch (Exception ex)
            {
                Log.WriteErrorLog(ex.Message);
            }
        }
    }

    static class Log
    {
        public static void WriteErrorLog(string message)
        {
            StreamWriter sw = File.CreateText(Application.ExecutablePath + @"ErrorLog.log");
            try
            {
                sw.Write(message);
            }
            finally
            {
                sw.Close();
            }
        }
    }

}
